{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "<a href=\"https://colab.research.google.com/drive/1AjVNW6ZZCOiFvnqek9KEOOxMGrMh0dUO?usp=sharing\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"></a>\n",
        "\n",
        "### 📄 Hypothetical Document Embeddings (HyDE) - Prompt Engineering\n",
        "\n",
        "HyDE is a method to improve retrieval and question-answering tasks using language models.\n",
        "\n",
        "### Key points:\n",
        "\n",
        "* 🔑 **Core concept:** Generate hypothetical documents to enhance retrieval of relevant information.\n",
        "\n",
        "* ⚙️ **Process:**\n",
        "  * Create a hypothetical answer or document for a given query\n",
        "  * Embed this hypothetical document\n",
        "  * Use the embedding to retrieve similar real documents\n",
        "\n",
        "* 🌟 **Advantages:**\n",
        "  * Improves retrieval accuracy, especially for complex queries\n",
        "  * Bridges the gap between query and document language\n",
        "\n",
        "* 💼 **Applications:** Information retrieval, question-answering systems, search engines.\n",
        "\n",
        "* 🚀 **Implementation:**\n",
        "  * Prompt the model to generate a plausible answer or document\n",
        "  * Use embedding models to convert text to vector representations\n",
        "  * Employ similarity search to find matching real documents\n",
        "\n",
        "* ⚖️ **Challenges:**\n",
        "  * Quality of hypothetical document affects retrieval performance\n",
        "  * Computational overhead of generating and embedding hypothetical documents\n",
        "\n",
        "* 🔄 **Variations:**\n",
        "  * Multi-HyDE: Generate multiple hypothetical documents\n",
        "  * Iterative HyDE: Refine hypothetical documents based on retrieved results\n",
        "\n",
        "* ✔️ **Effectiveness:** Often outperforms traditional keyword-based retrieval methods."
      ],
      "metadata": {
        "id": "Y2eqHW0TK87s"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "!pip install -q -U langchain-groq==0.2.4"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "KI4D1HL-LKaP",
        "outputId": "393e30bd-ee7c-4438-8c1e-5d9885a3b9ef"
      },
      "execution_count": 1,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\u001b[?25l   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/121.9 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K   \u001b[91m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[91m╸\u001b[0m\u001b[90m━━━\u001b[0m \u001b[32m112.6/121.9 kB\u001b[0m \u001b[31m6.5 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\r\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m121.9/121.9 kB\u001b[0m \u001b[31m2.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "from langchain_groq import ChatGroq\n",
        "from langchain.prompts import ChatPromptTemplate"
      ],
      "metadata": {
        "id": "dfHHptAFLMwj"
      },
      "execution_count": 2,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "import os\n",
        "import getpass"
      ],
      "metadata": {
        "id": "eZJGDTIMLOnP"
      },
      "execution_count": 3,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### 🔑 Provide Groq API Key\n",
        "\n",
        "- [Groq API Key](https://console.groq.com/keys)\n",
        "\n"
      ],
      "metadata": {
        "id": "rQrlkg_bLRZp"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "os.environ[\"GROQ_API_KEY\"] = getpass.getpass()"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "XI8sLK8uLTht",
        "outputId": "9f1e51e5-181c-46c2-d1f5-97f1889c4cab"
      },
      "execution_count": 4,
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "··········\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "llm = ChatGroq(\n",
        "    model=\"llama3-8b-8192\",\n",
        "    temperature=0.5\n",
        ")"
      ],
      "metadata": {
        "id": "0os_AIehLVh1"
      },
      "execution_count": 5,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "hyde_prompt = ChatPromptTemplate.from_messages(\n",
        "    [\n",
        "        (\"system\", \"\"\"You are an expert about a set of software for building LLM-powered applications called LangChain, LangGraph, LangServe, and LangSmith.\n",
        "\n",
        "          LangChain is a Python framework that provides a large set of integrations that can easily be composed to build LLM applications.\n",
        "          LangGraph is a Python package built on top of LangChain that makes it easy to build stateful, multi-actor LLM applications.\n",
        "          LangServe is a Python package built on top of LangChain that makes it easy to deploy a LangChain application as a REST API.\n",
        "          LangSmith is a platform that makes it easy to trace and test LLM applications.\n",
        "\n",
        "          Answer the user question as best you can. Answer as though you were writing a tutorial that addressed the user question.\"\"\"\n",
        "        ),\n",
        "        (\"human\", \"{input}\"),\n",
        "    ]\n",
        ")\n",
        "\n",
        "chain = hyde_prompt | llm"
      ],
      "metadata": {
        "id": "FToKQB7jLBYD"
      },
      "execution_count": 6,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "problem =  \"how to use multi-modal models in a chain and turn chain into a rest api?\"\n",
        "response = chain.invoke({\"input\": problem})\n",
        "print(response.content)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "0PWEvnMyLZSb",
        "outputId": "62d451de-b7dc-495e-9f76-88c3dd34d0c0"
      },
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Using multi-modal models in a LangChain and turning it into a REST API is a powerful way to build LLM-powered applications. Here's a step-by-step guide to help you achieve this.\n",
            "\n",
            "**Step 1: Integrate Multi-Modal Models in LangChain**\n",
            "\n",
            "To use multi-modal models in LangChain, you'll need to install the necessary packages and import them into your LangChain application. LangChain provides support for various multi-modal models, including image, video, audio, and text.\n",
            "\n",
            "Here's an example of how you can integrate a multi-modal model in LangChain:\n",
            "```python\n",
            "import langchain\n",
            "\n",
            "# Load the multi-modal model\n",
            "model = langchain.load_model('multi_modal_model')\n",
            "\n",
            "# Define the input and output formats\n",
            "input_format = 'text'\n",
            "output_format = 'image'\n",
            "\n",
            "# Create a LangChain node with the multi-modal model\n",
            "node = langchain.Node(model, input_format, output_format)\n",
            "```\n",
            "In this example, we're loading a multi-modal model using the `langchain.load_model()` function. We're then defining the input and output formats for the node. In this case, we're using text as the input format and image as the output format.\n",
            "\n",
            "**Step 2: Chain the Multi-Modal Node with Other Nodes**\n",
            "\n",
            "To create a chain of nodes, you can use the `langchain.Chain` class. This class allows you to define a sequence of nodes that will be executed in a specific order.\n",
            "\n",
            "Here's an example of how you can chain the multi-modal node with other nodes:\n",
            "```python\n",
            "chain = langchain.Chain()\n",
            "\n",
            "# Add the multi-modal node to the chain\n",
            "chain.add_node(node)\n",
            "\n",
            "# Add other nodes to the chain (e.g., text processing nodes, etc.)\n",
            "chain.add_node(langchain.Node('text_processing_model', input_format='text', output_format='text'))\n",
            "chain.add_node(langchain.Node('image_processing_model', input_format='image', output_format='image'))\n",
            "```\n",
            "In this example, we're creating a chain with three nodes: the multi-modal node, a text processing node, and an image processing node.\n",
            "\n",
            "**Step 3: Turn the Chain into a REST API using LangServe**\n",
            "\n",
            "To turn the LangChain into a REST API, you can use LangServe. LangServe is a Python package that provides a simple way to deploy LangChain applications as REST APIs.\n",
            "\n",
            "Here's an example of how you can use LangServe to deploy the chain as a REST API:\n",
            "```python\n",
            "import langserve\n",
            "\n",
            "# Create a LangServe app\n",
            "app = langserve.App()\n",
            "\n",
            "# Add the chain to the app\n",
            "app.add_chain(chain)\n",
            "\n",
            "# Start the app\n",
            "app.start()\n",
            "```\n",
            "In this example, we're creating a LangServe app and adding the chain to the app using the `add_chain()` method. We're then starting the app using the `start()` method.\n",
            "\n",
            "**Step 4: Use the REST API**\n",
            "\n",
            "Once the app is started, you can use the REST API to interact with the LangChain. You can send HTTP requests to the API to execute the chain and retrieve the output.\n",
            "\n",
            "Here's an example of how you can use the REST API to execute the chain:\n",
            "```bash\n",
            "curl -X POST \\\n",
            "  http://localhost:5000/execute \\\n",
            "  -H 'Content-Type: application/json' \\\n",
            "  -d '{\"input\": {\"text\": \"Hello, world!\"}}'\n",
            "```\n",
            "In this example, we're sending a POST request to the `/execute` endpoint with a JSON payload that contains the input data for the chain. The API will execute the chain and return the output.\n",
            "\n",
            "That's it! You've successfully integrated multi-modal models in LangChain and turned it into a REST API using LangServe. You can now use the REST API to build a wide range of LLM-powered applications.\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "ja7ZCUY2MJT2"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}